/*
 * Vector1D.cpp
 *
 *  Created on: Apr 9, 2010
 *      Author: andrew
 */

#include "Vector1D.h"
#include <iostream>
using namespace std;


/**
 * constructor
 */
Vector1D::Vector1D(int size, ...){
	x = new double[size];
	n = size;

	va_list Numbers;
	va_start(Numbers, size);
		for(int i = 0; i < n; i++ )
			x[i] = va_arg(Numbers, double);
	va_end(Numbers);
}

/*
 * Default constructor
 */
Vector1D::Vector1D() {
}

/**
 * constructor built from a passed in array
 */
Vector1D::Vector1D(int size, double xarray[]){
	n = size;
	x = new double[n];
	for(int i = 0; i < n; i++){
		x[i] = xarray[i];
	}
}

/**
 * Destructor
 */
Vector1D::~Vector1D() {
	delete[] x;
}

/**
 * Copy constructor
 */
Vector1D::Vector1D(const Vector1D& copyme){
	n = copyme.n;
	x = new double[n];
	for(int i = 0; i < n; i++){
		x[i] = copyme.x[i];
	}
}

/**
 * Assignment operator
 */
Vector1D& Vector1D::operator=(const Vector1D &vObj){
    if (this != &vObj)
    {
        delete[] x;
        n = vObj.n;
        x = new double[n];
        for(int i = 0; i < n; i++){
			x[i] = vObj.x[i];
		}
    }
    return *this;
}

/**
 * index elements of vector
 */
double& Vector1D::operator()(int i) const{
	return x[i];
}

/**
 * add two vectors
 */
Vector1D Vector1D::operator+(const Vector1D& right){
	Vector1D z = Vector1D(n);
	for(int i = 0; i < n; i++){
		z.x[i] = x[i] + right.x[i];
	}
	return z;
}

/**
 * subtract vector
 */
Vector1D Vector1D::operator-(const Vector1D& right){
	Vector1D z = Vector1D(right.length());
	for(int i = 0; i < right.length(); i++){
		z.x[i] = x[i] - right.x[i];
	}
	return z;
}

// Subtract double
Vector1D Vector1D::operator-(const double right){
	Vector1D z = Vector1D(n);
	for(int i = 0; i < n; i++){
		z.x[i] = x[i] - right;
	}
	return z;
}

/**
 * divide vector by a scalar
 */
Vector1D Vector1D::operator/(const double right){
	Vector1D z = Vector1D(n);
	for(int i = 0; i < n; i++){
		z.x[i] = x[i]/right;
	}
	return z;
}

/*
 * Multiply vector by a scalar
 */
Vector1D Vector1D::operator*(const double right) {
	Vector1D z = Vector1D(n);
	for(int i = 0; i < n; i++) {
		z.x[i] = x[i]*right;
	}
	return z;
}

/**
 * cross product of two vectors
 */
Vector1D Vector1D::cross(const Vector1D& y){
	Vector1D z = Vector1D(3);
	z.x[0] = x[1]*y.x[2] - x[2]*y.x[1];
	z.x[1] = x[2]*y.x[0] - x[0]*y.x[2];
	z.x[2] = x[0]*y.x[1] - x[1]*y.x[0];
	return z;
}

/**
 * return an array copied from elements in the vector
 */
double* Vector1D::getCopyOfArray() const{
	double* y = new double[n];
	for(int i = 0; i < n; i++){
		y[i] = x[i];
	}
	return y;
}

/*
 * Append vector to the end of current vector
 */
Vector1D Vector1D::appendVector(Vector1D& a) {
	Vector1D newVec(n+a.length());
	for(int i = 0; i < n; i++)
		newVec(i) = x[i];
	for(int i = 0; i < a.length(); i++)
		newVec(i+n) = a.x[i];

	return newVec;
}

Vector1D Vector1D::remove(int i){
	Vector1D y(n-1);

	int k = 0;
	for(int j = 0; j < n; j++){
		if(i != j) y(k) = x[j];
		k++;
	}
	return y;
}

void Vector1D::initConst(double alpha){
	for(int i = 0; i < n; i++){
		x[i] = alpha;
	}
}

Vector1D Vector1D::selectEntries(const Vector1D& toSelect){
	Vector1D y(toSelect.n);
	int i = 0;
	for (int j = 0; j < toSelect.n; j++){
		if(toSelect(j)){
			y(i++) = x[j];
		}
	}
	return y;
}

void Vector1D::printVector(void) const {
	for (int i = 0; i < n; i++) cout << x[i] << " ";
	cout << endl;
}

Vector1D Vector1D::vecNot(int i, int j) const{

	int rows = j-i+1;

	Vector1D xnew = Vector1D(rows);

	for (int idx = 0; idx < rows; idx++) {
			xnew(idx) = x[i+idx];
	}

	return xnew;
}
